using System.Reflection;
using UnityEngine;

namespace ReflectHelperLib.Helper
{
    // 反射相关的辅助类
    // 提供各种反射操作的工具方法
    internal static class ReflectHelper
    {
        // 设置目标对象的指定属性值
        public static bool SetPropertyValue(object targetObject, string propertyName, object value)
        {
            if (targetObject == null)
            {
                Debug.LogError($"目标对象为 null, 无法设置属性: {propertyName}");
                return false;
            }

            var property = targetObject.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            if (property == null)
            {
                Debug.LogError($"目标对象类型[{targetObject.GetType().Name}]不存在属性: [{propertyName}]");
                return false;
            }

            property.SetValue(targetObject, value);
            Debug.Log($"[{targetObject.GetType().Name}] 已通过反射设置属性[{propertyName}]: [{value}]");
            return true;
        }

        // 获取目标对象的指定属性值
        public static object? GetPropertyValue(object targetObject, string propertyName)
        {
            if (targetObject == null)
            {
                Debug.LogError($"目标对象为 null, 无法获取属性: {propertyName}");
                return null;
            }

            var property = targetObject.GetType().GetProperty(propertyName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            if (property == null)
            {
                Debug.LogError($"目标对象类型[{targetObject.GetType().Name}]不存在属性: [{propertyName}]");
                return null;
            }

            return property.GetValue(targetObject);
        }

        // 设置目标对象的指定字段值
        public static bool SetFieldValue(object targetObject, string fieldName, object value)
        {
            if (targetObject == null)
            {
                Debug.LogError($"目标对象为 null, 无法设置字段: {fieldName}");
                return false;
            }

            var field = targetObject.GetType().GetField(fieldName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            if (field == null)
            {
                Debug.LogError($"目标对象类型[{targetObject.GetType().Name}]不存在字段: [{fieldName}]");
                return false;
            }

            field.SetValue(targetObject, value);
            Debug.Log($"[{targetObject.GetType().Name}] 已通过反射设置字段[{fieldName}]: [{value}]");
            return true;
        }

        // 获取目标对象的指定字段值
        public static object? GetFieldValue(object targetObject, string fieldName)
        {
            if (targetObject == null)
            {
                Debug.LogError($"目标对象为 null, 无法获取字段: {fieldName}");
                return null;
            }

            var field = targetObject.GetType().GetField(fieldName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            if (field == null)
            {
                Debug.LogError($"目标对象类型[{targetObject.GetType().Name}]不存在字段: [{fieldName}]");
                return null;
            }

            return field.GetValue(targetObject);
        }

        // 设置目标对象的属性或字段值（自动判断）
        public static bool SetMemberValue(object targetObject, string memberName, object value)
        {
            if (targetObject == null)
            {
                Debug.LogError($"目标对象为 null, 无法设置成员: {memberName}");
                return false;
            }

            // 首先尝试作为属性设置
            var property = targetObject.GetType().GetProperty(memberName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            if (property != null && property.CanWrite)
            {
                property.SetValue(targetObject, value);
                Debug.Log($"[{targetObject.GetType().Name}] 已通过反射设置属性[{memberName}]: [{value}]");
                return true;
            }

            // 如果不是属性，尝试作为字段设置
            var field = targetObject.GetType().GetField(memberName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            if (field != null)
            {
                field.SetValue(targetObject, value);
                Debug.Log($"[{targetObject.GetType().Name}] 已通过反射设置字段[{memberName}]: [{value}]");
                return true;
            }

            Debug.LogError($"目标对象类型[{targetObject.GetType().Name}]不存在属性或字段: [{memberName}]");
            return false;
        }

        // 获取目标对象的属性或字段值（自动判断）
        public static object? GetMemberValue(object targetObject, string memberName)
        {
            if (targetObject == null)
            {
                Debug.LogError($"目标对象为 null, 无法获取成员: {memberName}");
                return null;
            }

            // 首先尝试作为属性获取
            var property = targetObject.GetType().GetProperty(memberName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            if (property != null && property.CanRead)
            {
                return property.GetValue(targetObject);
            }

            // 如果不是属性，尝试作为字段获取
            var field = targetObject.GetType().GetField(memberName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            if (field != null)
            {
                return field.GetValue(targetObject);
            }

            Debug.LogError($"目标对象类型[{targetObject.GetType().Name}]不存在属性或字段: [{memberName}]");
            return null;
        }
    }
}